"use strict";

Object.defineProperty(exports, "__esModule", {
	value: true
});
const create = Symbol();
const parent = Symbol();
const symbol = {
	create,
	parent

	/**
  * 作用域
  */
};class Scope {
	/**
  * 构造函数
  * @param {Scope} 父作用域
  */
	constructor(parent) {
		if (parent instanceof Scope) {
			this[symbol.parent] = parent;
		}
	}

	/**
  * 创建变量
  * @param {String} key 变量名
  * @param * 变量值
  * 
  */
	[create](key, value) {
		if (typeof key !== "string") {
			return;
		}
		return this[key] = value;
	}
}

let proxy = {
	get(target, key, receiver) {
		if (key === create) {
			return target[create].bind(target);
		}
		if (key === parent) {
			return target[parent];
		}
		if (typeof key !== "string") {
			return;
		}
		if (new Set(Object.keys(target)).has(key)) {
			return target[key];
		} else if (target[parent]) {
			return target[parent][key];
		}
	},
	set(target, key, value, receiver) {
		if (typeof key !== "string") {
			return;
		}
		if (new Set(Object.keys(target)).has(key)) {
			target[key] = value;
		} else if (target[parent]) {
			target[parent][key] = value;
		} else {
			target[create](key, value);
		}
		return true;
	},
	has(target, key) {
		return new Set(Object.keys(target)).has(key) || target[parent] && key in target[parent];
	},
	deleteProperty(target, key) {
		if (typeof key !== "string") {
			return false;
		}
		if (new Set(Object.keys(target)).has(key)) {
			return delete target[key];
		} else if (target[parent]) {
			return delete target[parent][key];
		} else {
			return false;
		}
	},
	ownKeys(target) {
		let ret;
		if (target[parent]) {
			ret = new Set(Object.getOwnPropertyNames(target[parent]));
			Object.keys(target).map(x => ret.add(x));
		} else {
			ret = new Set(Object.keys(target));
		}
		return [...ret];
	},
	defineProperty(target, propKey, propDesc) {
		return false;
	},
	preventExtensions(target) {
		return false;
	},
	setPrototypeOf(target, proto) {
		return false;
	}
};
/**
 * 创建作用域
 * @param {Scope} parent 父作用域
 * @return {Scope} 创建的作用域
 */
let scope = function scope(parent) {
	return new Proxy(new Scope(parent), proxy);
};
scope.symbol = symbol;
scope.create = create;
scope.is = s => s instanceof Scope;
exports.default = scope;